
package com.shop.cloud.weixin.admin.controller;

import cn.binarywang.wx.miniapp.api.WxMaCodeService;
import cn.binarywang.wx.miniapp.bean.code.WxMaCodeAuditStatus;
import cn.binarywang.wx.miniapp.bean.code.WxMaCodeSubmitAuditRequest;
import cn.binarywang.wx.miniapp.constant.WxMaApiUrlConstants;
import cn.hutool.core.codec.Base64Encoder;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.shop.cloud.common.core.constant.CommonConstants;
import com.shop.cloud.common.core.util.R;
import com.shop.cloud.weixin.admin.config.open.WxOpenConfiguration;
import com.shop.cloud.weixin.admin.service.WxMaCodeAuditService;
import com.shop.cloud.weixin.admin.service.WxMaCodeCommitService;
import com.shop.cloud.weixin.common.constant.WxReturnCode;
import com.shop.cloud.weixin.common.entity.WxMaCodeCommitRequest;
import com.shop.cloud.weixin.common.entity.WxMaCodeAudit;
import com.shop.cloud.weixin.common.entity.WxMaCodeCommit;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpMaterialService;
import me.chanjar.weixin.open.api.WxOpenMaService;
import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 小程序代码管理
 *
 * @author
 * @date 202-01-25 15:39:39
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/open/ma/code")
@Tag(description = "openmacode", name = "小程序代码管理")
public class WxMaCodeTemplateController {

	private final WxMaCodeCommitService wxMaCodeCommitService;
	private final WxMaCodeAuditService wxMaCodeAuditService;

	/**
	* 获取代码模板列表
	* @return
	*/
	@Operation(summary = "获取代码模板列表")
	@GetMapping("/template/list")
	@PreAuthorize("@ato.hasAuthority('wxma:code:index')")
	public R getCodeTemplateList() {
		try {
			List<WxOpenMaCodeTemplate> list = WxOpenConfiguration.getOpenService().getWxOpenComponentService().getTemplateList(0);
			return R.ok(list);
		} catch (WxErrorException e) {
			e.printStackTrace();
			log.error("getCodeTemplateList：", e);
			return WxReturnCode.wxErrorExceptionHandler(e);
		}

	}

	/**
	 * 上传小程序代码
	 * @return
	 */
	@Operation(summary = "上传小程序代码")
	@PostMapping("/{appId}/commit")
	@PreAuthorize("@ato.hasAuthority('wxma:code:index')")
	public R codeCommit(@PathVariable("appId") String appId, @RequestBody WxMaCodeCommitRequest commitRequest) {
		try {
			//上传小程序代码
			WxOpenConfiguration.getOpenService().getWxOpenComponentService().getWxMaServiceByAppid(appId).post(WxMaApiUrlConstants.Code.COMMIT_URL,commitRequest.toJson());
			//保存记录
			WxMaCodeCommit wxMaCodeCommit = new WxMaCodeCommit();
			wxMaCodeCommit.setAppId(appId);
			wxMaCodeCommit.setCodeVersion(commitRequest.getUserVersion());
			wxMaCodeCommitService.save(wxMaCodeCommit);
		} catch (WxErrorException e) {
			e.printStackTrace();
			log.error("codeCommit：", e);
			return WxReturnCode.wxErrorExceptionHandler(e);
		}
		return R.ok();
	}

	/**
	 * 获取已上传的代码的页面列表
	 * @return
	 */
	@Operation(summary = "获取已上传的代码的页面列表")
	@GetMapping("/{appId}/page")
	@PreAuthorize("@ato.hasAuthority('wxma:code:index')")
	public R getPage(@PathVariable("appId") String appId) {
		try {
			WxOpenMaService wxOpenMaService = WxOpenConfiguration.getOpenService().getWxOpenComponentService().getWxMaServiceByAppid(appId);
			List<String> listPage = wxOpenMaService.getCodeService().getPage();
			Map<String, Object> map = new HashMap();
			map.put("pages", listPage);
			map.put("wxMaCodeCommit", wxMaCodeCommitService.getOne(Wrappers.<WxMaCodeCommit>query().lambda()
					.eq(WxMaCodeCommit::getAppId, appId)
					.orderByDesc(WxMaCodeCommit::getCreateTime)
					.last("limit 1")));
			return R.ok(map);
		} catch (WxErrorException e) {
			if(e.getError().getErrorCode() == 86001){
				return R.ok(new ArrayList<>());
			}
			e.printStackTrace();
			log.error("getPage：", e);
			return WxReturnCode.wxErrorExceptionHandler(e);
		}
	}

	/**
	 * 获取体验版二维码
	 * @return
	 */
	@Operation(summary = "获取体验版二维码")
	@GetMapping("/{appId}/qrcode")
	@PreAuthorize("@ato.hasAuthority('wxma:code:index')")
	public R getQrCode(@PathVariable("appId") String appId){
		try {
			WxOpenMaService wxOpenMaService = WxOpenConfiguration.getOpenService().getWxOpenComponentService().getWxMaServiceByAppid(appId);
			return R.ok(wxOpenMaService.getCodeService().getQrCode(null));
		} catch (WxErrorException e) {
			e.printStackTrace();
			log.error("getQrcode：", e);
			return WxReturnCode.wxErrorExceptionHandler(e);
		}
	}

	/**
	 * 提交审核
	 * @return
	 */
	@Operation(summary = "提交审核")
	@PostMapping("/{appId}/submit")
	@PreAuthorize("@ato.hasAuthority('wxma:code:index')")
	public R codeSubmit(@PathVariable("appId") String appId, @RequestBody WxMaCodeAudit wxMaCodeAudit) {
		try {
			WxMaCodeService wxMaCodeService = WxOpenConfiguration.getOpenService().getWxOpenComponentService().getWxMaServiceByAppid(appId).getCodeService();
			WxMaCodeSubmitAuditRequest auditRequest = new WxMaCodeSubmitAuditRequest();
			auditRequest.setOrderPath("pages/order/order-list/index");
			//提交审核
			long auditId = wxMaCodeService.submitAudit(auditRequest);
			//保存记录
			wxMaCodeAudit.setAuditId(String.valueOf(auditId));
			wxMaCodeAuditService.save(wxMaCodeAudit);
		} catch (WxErrorException e) {
			e.printStackTrace();
			log.error("codeSubmit：", e);
			return WxReturnCode.wxErrorExceptionHandler(e);
		}
		return R.ok();
	}

	/**
	 * 查询最新一次提交的审核状态
	 * @return
	 */
	@Operation(summary = "查询最新一次提交的审核状态")
	@GetMapping("/{appId}/auditstatus")
	@PreAuthorize("@ato.hasAuthority('wxma:code:index')")
	public R getLatestAuditstatus(@PathVariable("appId") String appId) {
		WxMaCodeAuditStatus wxMaCodeAuditStatus = new WxMaCodeAuditStatus();
		Map<String, Object> map = new HashMap<>();
		try {
			WxOpenMaService wxOpenMaService = WxOpenConfiguration.getOpenService().getWxOpenComponentService().getWxMaServiceByAppid(appId);
			wxMaCodeAuditStatus =  wxOpenMaService.getCodeService().getLatestAuditStatus();
			map.put("wxMaCodeAuditStatus", wxMaCodeAuditStatus);
			if(wxMaCodeAuditStatus != null && wxMaCodeAuditStatus.getAuditId() != null){
				WxMaCodeAudit wxMaCodeAudit = wxMaCodeAuditService.getOne(Wrappers.<WxMaCodeAudit>query().lambda()
						.eq(WxMaCodeAudit::getAppId, appId)
						.eq(WxMaCodeAudit::getAuditId, wxMaCodeAuditStatus.getAuditId()));
				map.put("wxMaCodeAudit", wxMaCodeAudit);
			}
		} catch (WxErrorException e) {
			if(e.getError().getErrorCode() == 85058){
				return R.ok(wxMaCodeAuditStatus);
			}
			e.printStackTrace();
			log.error("getLatestAuditstatus：", e);
			return WxReturnCode.wxErrorExceptionHandler(e);
		}
		return R.ok(map);
	}

	/**
	 * 审核撤回
	 * @return
	 */
	@Operation(summary = "审核撤回")
	@GetMapping("/{appId}/undocodeaudit")
	@PreAuthorize("@ato.hasAuthority('wxma:code:index')")
	public R undoCodeAudit(@PathVariable("appId") String appId) {
		try {
			WxOpenConfiguration.getOpenService().getWxOpenComponentService().getWxMaServiceByAppid(appId).getCodeService().undoCodeAudit();
		} catch (WxErrorException e) {
			e.printStackTrace();
			log.error("undoCodeAudit：", e);
			return WxReturnCode.wxErrorExceptionHandler(e);
		}
		return R.ok();
	}

	/**
	 * 发布已通过审核的小程序
	 * @return
	 */
	@Operation(summary = "发布已通过审核的小程序")
	@PostMapping("/{appId}/{wxMaCodeAuditId}/release")
	@PreAuthorize("@ato.hasAuthority('wxma:code:index')")
	public R codeRelease(@PathVariable("appId") String appId, @PathVariable("wxMaCodeAuditId") String wxMaCodeAuditId) {
		try {
			WxOpenConfiguration.getOpenService().getWxOpenComponentService().getWxMaServiceByAppid(appId).getCodeService().release();
			WxMaCodeAudit wxMaCodeAudit = new WxMaCodeAudit();
			wxMaCodeAudit.setId(wxMaCodeAuditId);
			wxMaCodeAudit.setHavRelease(CommonConstants.YES);
			wxMaCodeAuditService.updateById(wxMaCodeAudit);
		} catch (WxErrorException e) {
			e.printStackTrace();
			log.error("codeRelease：", e);
			return WxReturnCode.wxErrorExceptionHandler(e);
		}
		return R.ok();
	}

	/**
	 * 获取截图示例
	 * @return
	 */
	@Operation(summary = "获取截图示例")
	@GetMapping("/{appId}/screenshot/{mediaId}")
	@PreAuthorize("@ato.hasAuthority('wxma:code:index')")
	public R getScreenShot(@PathVariable("appId") String appId,@PathVariable("mediaId") String mediaId) throws IOException {
		try {
			WxMpMaterialService wxMpMaterialService = WxOpenConfiguration.getOpenService().getWxOpenComponentService().getWxMpServiceByAppid(appId).getMaterialService();
			InputStream in = wxMpMaterialService.materialImageOrVoiceDownload(mediaId);
			byte[] data = new byte[in.available()];
			in.read(data);
			in.close();
			//对字节数组Base64编码
			Base64Encoder encoder = new Base64Encoder();
			//返回Base64编码过的字节数组字符串
			String base64 = encoder.encode(data);
			return R.ok(base64);
		} catch (WxErrorException e) {
			e.printStackTrace();
			log.error("getScreenShot：", e);
			return WxReturnCode.wxErrorExceptionHandler(e);
		}
	}
}
